#include "stdafx.h"
#include "XmlFileFilter.h"

CXmlFileFilter::CXmlFileFilter(void)
{
	if (g_csUtProjCommandLineParser.IsInputTestSetDefined())
	{
		//define is that connection name template or file
		VARIANT_BOOL vb = VARIANT_FALSE;
		if (FAILED(m_spDocument.CreateInstance(CLSID_DOMDocument)) ||
			FAILED(m_spDocument->load(CComVariant(g_csUtProjCommandLineParser.GetInputTestSetPath()), &vb)) ||
			(vb == VARIANT_FALSE))
		{
			m_spDocument = NULL;
		}
	}
}

CXmlFileFilter::~CXmlFileFilter(void)
{
}

BOOL CXmlFileFilter::DefineTestsToRun(TestPackTransData & rTestPackTransData)
{
	ATLASSERT(IsLoaded());
	if (IsLoaded() == FALSE)
		return FALSE;

	//reset all tests and groups
	Reset(rTestPackTransData);

	//set only those tests and groups that are present in a xml file
	IXMLDOMNodeListPtr spGroups;
	long nGroupCount = 0;
	if (SUCCEEDED(m_spDocument->selectNodes(CComBSTR(L"testrun/group[@name]"), &spGroups)) &&
		SUCCEEDED(spGroups->get_length(&nGroupCount)))
	{
		for (long nGroup = 0; nGroup < nGroupCount; ++nGroup)
		{
			IXMLDOMNodePtr spNode;
			IXMLDOMElementPtr spGroup;

			if (SUCCEEDED(spGroups->get_item(nGroup, &spNode)) &&
				(spGroup = spNode))
			{
				ProcessGroup(nGroup, spGroup, rTestPackTransData);
			}
		}
	}
	return TRUE;
}

void CXmlFileFilter::Reset(TestPackTransData & rTestPackTransData)
{
	//reset all tests and groups
	size_t tGroupCount = rTestPackTransData.aTestGroups.GetCount();
	for (size_t tGroup = 0; tGroup < tGroupCount; ++tGroup)
	{
		TestGroupTransData & rTestGroupTransData = rTestPackTransData.aTestGroups.GetAt(tGroup);
		rTestGroupTransData.bRun = FALSE;
		size_t tTestCount = rTestGroupTransData.aTestRuns.GetCount();
		for (size_t tTest = 0; tTest < tTestCount; ++tTest)
		{
			rTestGroupTransData.aTestRuns.GetAt(tTest).bRun = FALSE;
		}
	}
}

void CXmlFileFilter::ProcessGroup(const long nGroup, const IXMLDOMElementPtr & spGroup, TestPackTransData & rTestPackTransData)
{
	static CComBSTR bstrName(L"name");
	static CComBSTR bstrSelectTests(L"ut[@name]");
	CComVariant vtName;

	if (SUCCEEDED(spGroup->getAttribute(bstrName, &vtName)) &&
		(vtName.vt == VT_BSTR))
	{
		//find a group with the given name if any
		for (size_t t = 0; t < rTestPackTransData.aTestGroups.GetCount(); ++t)
		{
			TestGroupTransData & rTestGroupTransData = rTestPackTransData.aTestGroups.GetAt(t);
			if (rTestGroupTransData.wstrName == vtName.bstrVal)
			{
				rTestGroupTransData.bRun = TRUE;
				rTestGroupTransData.lParam = nGroup;
				
				long nTestCount = 0;
				IXMLDOMNodeListPtr spTests;
				IXMLDOMNodePtr spNode;
				IXMLDOMElementPtr spTest;
				if (SUCCEEDED(spGroup->selectNodes(bstrSelectTests, &spTests)) &&
					SUCCEEDED(spTests->get_length(&nTestCount)))
				{
					for (long n = 0; n < nTestCount; ++n)
					{
						if (SUCCEEDED(spTests->get_item(n, &spNode)) &&
							(spTest = spNode))
						{
							if (SUCCEEDED(spTest->getAttribute(bstrName, &vtName)) &&
								(vtName.vt == VT_BSTR))
							{
								for (size_t t1 = 0; t1 < rTestGroupTransData.aTestRuns.GetCount(); ++t1)
								{
									TestRunTransData & rTestRunTransData = rTestGroupTransData.aTestRuns.GetAt(t1);
									if (rTestRunTransData.wstrName == vtName.bstrVal)
									{
										rTestRunTransData.bRun = TRUE;
										rTestRunTransData.lParam = n;
										break;
									}
								}
							}
						}
					} //for (long n = 0;
				}
				break;
			} //if (rTestGroupTransData.wstrName == vtName.bstrVal)
		} //for (size_t t = 0;
	}
}